package com.example.huixue.controller;

import com.example.huixue.common.PageResult;
import com.example.huixue.common.Result;
import com.example.huixue.dto.LoginRequest;
import com.example.huixue.dto.RegisterRequest;
import com.example.huixue.dto.UserInfoResponse;
import com.example.huixue.entity.User;
import com.example.huixue.service.UserService;
import com.example.huixue.util.JwtUtil;
import jakarta.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@RestController
@RequestMapping("/api/users")
@CrossOrigin(origins = "*")
public class UserController {
    
    private static final Logger logger = LoggerFactory.getLogger(UserController.class);
    
    @Autowired
    private UserService userService;
    
    @Autowired
    private JwtUtil jwtUtil;
    
    @Autowired
    private PasswordEncoder passwordEncoder;
    
    /**
     * 通用token验证方法
     */
    private Integer validateTokenAndGetUserId(String token) {
        if (token == null || !token.startsWith("Bearer ")) {
            throw new RuntimeException("未提供有效的认证令牌");
        }
        
        String jwtToken = token.substring(7); // 去掉"Bearer "前缀
        
        // 处理JWT token和mock token（向后兼容）
        if (jwtToken.startsWith("mock-jwt-token-") || jwtToken.startsWith("mock-admin-token") || jwtToken.startsWith("mock-user-token")) {
            // 处理mock token（向后兼容）
            if (jwtToken.startsWith("mock-jwt-token-")) {
                String userIdStr = jwtToken.replace("mock-jwt-token-", "");
                return Integer.parseInt(userIdStr);
            } else if (jwtToken.equals("mock-admin-token")) {
                return 1; // 假设管理员ID为1
            } else if (jwtToken.equals("mock-user-token")) {
                return 2; // 假设普通用户ID为2
            }
        } else {
            // 处理真实JWT token
            if (!jwtUtil.validateToken(jwtToken)) {
                throw new RuntimeException("token已过期或无效，请重新登录");
            }
            return jwtUtil.getUserIdFromToken(jwtToken);
        }
        
        throw new RuntimeException("无效的token格式");
    }
    
    /**
     * 验证用户token并获取用户信息（只处理普通用户token）
     */
    private Map<String, Object> validateTokenAndGetUserInfo(String token) {
        if (token == null || !token.startsWith("Bearer ")) {
            throw new RuntimeException("未提供有效的认证令牌");
        }
        
        String jwtToken = token.substring(7); // 去掉"Bearer "前缀
        
        if (jwtToken.startsWith("mock-jwt-token-") || jwtToken.startsWith("mock-user-token")) {
            // 处理mock token（向后兼容）
            Integer userId = null;
            
            if (jwtToken.startsWith("mock-jwt-token-")) {
                String userIdStr = jwtToken.replace("mock-jwt-token-", "");
                userId = Integer.parseInt(userIdStr);
            } else if (jwtToken.equals("mock-user-token")) {
                userId = 2; // 假设普通用户ID为2
            }
            
            // 从users表查找
            User user = userService.findById(userId);
            if (user != null) {
                Map<String, Object> userInfo = new HashMap<>();
                userInfo.put("userId", user.getUserId());
                userInfo.put("username", user.getUsername());
                userInfo.put("role", user.getUserRole());
                userInfo.put("type", "ADMIN".equals(user.getUserRole()) ? "admin" : "user");
                return userInfo;
            }
            
            throw new RuntimeException("用户不存在");
        } else {
            // 处理真实JWT token
            if (!jwtUtil.validateToken(jwtToken)) {
                throw new RuntimeException("token已过期或无效，请重新登录");
            }
            
            // 检查是否为用户token（不是管理员token）
            String role = jwtUtil.getRoleFromToken(jwtToken);
            String userType = jwtUtil.getUserTypeFromToken(jwtToken);
            
            if ("ADMIN".equals(role) && "admin".equals(userType)) {
                throw new RuntimeException("管理员请使用管理后台");
            }
            
            Integer userId = jwtUtil.getUserIdFromToken(jwtToken);
            String username = jwtUtil.getUsernameFromToken(jwtToken);
            
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("userId", userId);
            userInfo.put("username", username);
            userInfo.put("role", role);
            userInfo.put("type", "user");
            return userInfo;
        }
    }
    
    /**
     * 用户登录（支持用户名或邮箱）
     */
    @PostMapping("/login")
    public Result<Map<String, Object>> login(@RequestBody Map<String, String> loginData) {
        try {
            String usernameOrEmail = loginData.get("usernameOrEmail");
            String password = loginData.get("password");
            
            logger.info("用户登录请求: {}", usernameOrEmail);
            
            if (usernameOrEmail == null || usernameOrEmail.trim().isEmpty()) {
                return Result.error("用户名或邮箱不能为空");
            }
            
            if (password == null || password.trim().isEmpty()) {
                return Result.error("密码不能为空");
            }
            
            // 查找用户
            User user = userService.findByUsernameOrEmail(usernameOrEmail.trim());
            
            if (user == null) {
                logger.warn("登录失败: 用户不存在 - {}", usernameOrEmail);
                return Result.error("用户名/邮箱或密码错误");
            }
            
            // 验证密码
            if (!passwordEncoder.matches(password, user.getPassword())) {
                logger.warn("登录失败: 密码错误 - {}", usernameOrEmail);
                return Result.error("用户名/邮箱或密码错误");
            }
            
            // 更新最后登录时间
            user.setLastLogin(LocalDateTime.now());
            userService.updateLastLogin(user.getUserId(), user.getLastLogin());
            
            // 返回用户信息（不包含密码）
            Map<String, Object> result = new HashMap<>();
            result.put("userId", user.getUserId());
            result.put("username", user.getUsername());
            result.put("email", user.getEmail());
            result.put("userRole", user.getUserRole());
            result.put("lastLogin", user.getLastLogin());
            
            // 生成JWT token
            String token = jwtUtil.generateToken(user.getUserId(), user.getUsername(), user.getUserRole());
            result.put("token", token);
            
            logger.info("用户登录成功: {} (角色: {})", user.getUsername(), user.getUserRole());
            return Result.success("登录成功", result);
            
        } catch (Exception e) {
            logger.error("登录过程发生错误", e);
            return Result.error("登录失败：" + e.getMessage());
        }
    }
    
    /**
     * 用户注册
     */
    @PostMapping("/register")
    public Result<Map<String, Object>> register(@RequestBody User user) {
        try {
            logger.info("用户注册请求: {}", user.getUsername());
            
            // 验证输入
            if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
                return Result.error("用户名不能为空");
            }
            
            if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
                return Result.error("邮箱不能为空");
            }
            
            if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
                return Result.error("密码不能为空");
            }
            
            // 检查用户名是否已存在
            if (userService.existsByUsername(user.getUsername().trim())) {
                logger.warn("注册失败: 用户名已存在 - {}", user.getUsername());
                return Result.error("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            if (userService.existsByEmail(user.getEmail().trim())) {
                logger.warn("注册失败: 邮箱已存在 - {}", user.getEmail());
                return Result.error("邮箱已存在");
            }
            
            // 设置默认值
            user.setUsername(user.getUsername().trim());
            user.setEmail(user.getEmail().trim());
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            user.setUserRole("USER");
            user.setStatus("ACTIVE");
            user.setRegisterDate(LocalDateTime.now());
            
            // 保存用户
            userService.save(user);
            
            // 注册成功后生成token，返回用户信息以支持自动登录
            String token = jwtUtil.generateToken(user.getUserId(), user.getUsername(), user.getUserRole());
            
            Map<String, Object> result = new HashMap<>();
            result.put("userId", user.getUserId());
            result.put("username", user.getUsername());
            result.put("email", user.getEmail());
            result.put("userRole", user.getUserRole());
            result.put("registerDate", user.getRegisterDate());
            result.put("status", user.getStatus());
            result.put("token", token);
            
            logger.info("用户注册成功: {}", user.getUsername());
            return Result.success("注册成功", result);
            
        } catch (Exception e) {
            logger.error("注册过程发生错误", e);
            return Result.error("注册失败：" + e.getMessage());
        }
    }
    
    /**
     * 获取当前用户信息
     */
    @GetMapping("/me")
    public Result<Map<String, Object>> getCurrentUser(@RequestHeader("Authorization") String token) {
        try {
            Integer userId = validateTokenAndGetUserId(token);
            
            // 根据ID查找用户
            User user = userService.findById(userId);
            if (user == null) {
                return Result.error("用户不存在");
            }
            
            Map<String, Object> result = new HashMap<>();
            result.put("userId", user.getUserId());
            result.put("username", user.getUsername());
            result.put("email", user.getEmail());
            result.put("phone", user.getPhone());
            result.put("registerDate", user.getRegisterDate());
            result.put("userRole", user.getUserRole());
            result.put("lastLogin", user.getLastLogin());
            result.put("status", user.getStatus());
            
            return Result.success(result);
            
        } catch (Exception e) {
            return Result.error("获取用户信息失败：" + e.getMessage());
        }
    }
    
    /**
     * 用户登出
     */
    @PostMapping("/logout")
    public Result<String> logout() {
        // 这里可以将token加入黑名单
        return Result.success("登出成功");
    }
    
    /**
     * 获取当前用户信息
     */
    @GetMapping("/profile")
    public Result<UserInfoResponse> getUserProfile(@RequestHeader("Authorization") String token) {
        try {
            Integer userId = validateTokenAndGetUserId(token);
            
            UserInfoResponse user = userService.getUserInfo(userId);
            return Result.success(user);
        } catch (Exception e) {
            return Result.error("获取用户信息失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新用户信息
     */
    @PutMapping("/profile")
    public Result<UserInfoResponse> updateUserProfile(@RequestHeader("Authorization") String token,
                                                       @RequestBody User updateUser) {
        try {
            Integer userId = validateTokenAndGetUserId(token);
            UserInfoResponse user = userService.updateUserInfo(userId, updateUser);
            return Result.success("更新成功", user);
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 修改密码
     */
    @PutMapping("/password")
    public Result<String> changePassword(@RequestHeader("Authorization") String token,
                                       @RequestBody Map<String, String> passwordData) {
        try {
            Integer userId = validateTokenAndGetUserId(token);
            String oldPassword = passwordData.get("oldPassword");
            String newPassword = passwordData.get("newPassword");
            
            if (oldPassword == null || newPassword == null) {
                return Result.error("旧密码和新密码不能为空");
            }
            
            userService.changePassword(userId, oldPassword, newPassword);
            return Result.success("密码修改成功");
        } catch (RuntimeException e) {
            return Result.error(e.getMessage());
        }
    }
    
    /**
     * 分页查询用户列表（管理员功能）
     */
    @GetMapping("/list")
    public Result<PageResult<UserInfoResponse>> getUserList(@RequestHeader("Authorization") String token,
                                                            @RequestParam(defaultValue = "1") int current,
                                                            @RequestParam(defaultValue = "10") int size,
                                                            @RequestParam(required = false) String keyword) {
        try {
            logger.info("管理员获取用户列表请求");
            
            Integer userId = validateTokenAndGetUserId(token);
            
            PageResult<UserInfoResponse> result = userService.getUsersWithPagination(current, size, keyword);
            logger.info("成功返回用户列表，共 {} 条记录", result.getTotal());
            return Result.success(result);
        } catch (Exception e) {
            logger.error("获取用户列表失败", e);
            return Result.error("获取用户列表失败：" + e.getMessage());
        }
    }
    
    /**
     * 添加用户（管理员功能）
     */
    @PostMapping("/add")
    public Result<String> addUser(@RequestHeader("Authorization") String token,
                                 @RequestBody User user) {
        try {
            Integer userId = validateTokenAndGetUserId(token);
            
            // 验证输入
            if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
                return Result.error("用户名不能为空");
            }
            
            if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
                return Result.error("邮箱不能为空");
            }
            
            if (user.getPassword() == null || user.getPassword().trim().isEmpty()) {
                return Result.error("密码不能为空");
            }
            
            // 检查用户名是否已存在
            if (userService.existsByUsername(user.getUsername().trim())) {
                return Result.error("用户名已存在");
            }
            
            // 检查邮箱是否已存在
            if (userService.existsByEmail(user.getEmail().trim())) {
                return Result.error("邮箱已存在");
            }
            
            // 设置默认值
            user.setUsername(user.getUsername().trim());
            user.setEmail(user.getEmail().trim());
            user.setPassword(passwordEncoder.encode(user.getPassword()));
            user.setUserRole(user.getUserRole() != null ? user.getUserRole() : "USER");
            user.setStatus(user.getStatus() != null ? user.getStatus() : "ACTIVE");
            user.setRegisterDate(LocalDateTime.now());
            
            // 保存用户
            userService.save(user);
            
            logger.info("管理员添加用户成功: {}", user.getUsername());
            return Result.success("用户添加成功");
            
        } catch (Exception e) {
            logger.error("添加用户失败", e);
            return Result.error("添加用户失败：" + e.getMessage());
        }
    }
    
    /**
     * 编辑用户（管理员功能）
     */
    @PutMapping("/{userId}/edit")
    public Result<String> editUser(@RequestHeader("Authorization") String token,
                                  @PathVariable Integer userId,
                                  @RequestBody User user) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            // 验证用户是否存在
            User existingUser = userService.findById(userId);
            if (existingUser == null) {
                return Result.error("用户不存在");
            }
            
            // 验证输入
            if (user.getUsername() == null || user.getUsername().trim().isEmpty()) {
                return Result.error("用户名不能为空");
            }
            
            if (user.getEmail() == null || user.getEmail().trim().isEmpty()) {
                return Result.error("邮箱不能为空");
            }
            
            // 检查用户名是否被其他用户使用
            User userWithSameName = userService.findByUsername(user.getUsername().trim());
            if (userWithSameName != null && !userWithSameName.getUserId().equals(userId)) {
                return Result.error("用户名已被其他用户使用");
            }
            
            // 检查邮箱是否被其他用户使用
            User userWithSameEmail = userService.findByEmail(user.getEmail().trim());
            if (userWithSameEmail != null && !userWithSameEmail.getUserId().equals(userId)) {
                return Result.error("邮箱已被其他用户使用");
            }
            
            // 更新用户信息
            existingUser.setUsername(user.getUsername().trim());
            existingUser.setEmail(user.getEmail().trim());
            
            // 如果提供了新密码，则更新密码
            if (user.getPassword() != null && !user.getPassword().trim().isEmpty()) {
                existingUser.setPassword(passwordEncoder.encode(user.getPassword()));
            }
            
            if (user.getUserRole() != null) {
                existingUser.setUserRole(user.getUserRole());
            }
            
            if (user.getStatus() != null) {
                existingUser.setStatus(user.getStatus());
            }
            
            // 保存更新
            userService.update(existingUser);
            
            logger.info("管理员编辑用户成功: {}", existingUser.getUsername());
            return Result.success("用户信息更新成功");
            
        } catch (Exception e) {
            logger.error("编辑用户失败", e);
            return Result.error("编辑用户失败：" + e.getMessage());
        }
    }

    /**
     * 更新用户角色（管理员功能）
     */
    @PutMapping("/{userId}/role")
    public Result<String> updateUserRole(@RequestHeader("Authorization") String token,
                                       @PathVariable Integer userId,
                                       @RequestBody Map<String, String> roleData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            String role = roleData.get("role");
            if (role == null) {
                return Result.error("角色不能为空");
            }
            
            userService.updateUserRole(userId, role);
            logger.info("用户 {} 的角色被更新为 {}", userId, role);
            return Result.success("角色更新成功");
        } catch (Exception e) {
            logger.error("更新用户角色失败", e);
            return Result.error("更新用户角色失败：" + e.getMessage());
        }
    }
    
    /**
     * 更新用户状态（管理员功能）
     */
    @PutMapping("/{userId}/status")
    public Result<String> updateUserStatus(@RequestHeader("Authorization") String token,
                                         @PathVariable Integer userId,
                                         @RequestBody Map<String, String> statusData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            String status = statusData.get("status");
            if (status == null) {
                return Result.error("状态不能为空");
            }
            
            userService.updateUserStatus(userId, status);
            return Result.success("状态更新成功");
        } catch (Exception e) {
            logger.error("更新用户状态失败", e);
            return Result.error("更新用户状态失败：" + e.getMessage());
        }
    }
    
    /**
     * 删除用户（管理员功能）
     */
    @DeleteMapping("/{userId}") 
    public Result<String> deleteUser(@RequestHeader("Authorization") String token,
                                   @PathVariable Integer userId) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            userService.deleteUser(userId);
            logger.info("用户 {} 被删除", userId);
            return Result.success("用户删除成功");
        } catch (Exception e) {
            logger.error("删除用户失败", e);
            return Result.error("删除用户失败：" + e.getMessage());
        }
    }
    
    /**
     * 验证token有效性
     */
    @PostMapping("/validate-token")
    public Result<Map<String, Object>> validateToken(@RequestHeader("Authorization") String token) {
        try {
            Map<String, Object> userInfo = validateTokenAndGetUserInfo(token);
            return Result.success(userInfo);
        } catch (Exception e) {
            return Result.error(401, "token验证失败：" + e.getMessage());
        }
    }
    
    /**
     * 初始化管理员（仅在系统没有管理员时可用）
     */
    @PostMapping("/init-admin")
    public Result<String> initAdmin(@RequestHeader("Authorization") String token,
                                   @RequestBody Map<String, Integer> requestData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            // 检查系统中是否已有管理员
            if (userService.hasAdmin()) {
                return Result.error("系统中已存在管理员，无法初始化");
            }
            
            Integer targetUserId = requestData.get("userId");
            if (targetUserId == null) {
                targetUserId = currentUserId; // 如果没有指定用户ID，则提升当前用户
            }
            
            // 将指定用户提升为管理员
            userService.updateUserRole(targetUserId, "ADMIN");
            logger.info("用户 {} 被提升为管理员", targetUserId);
            
            return Result.success("管理员初始化成功");
        } catch (Exception e) {
            logger.error("初始化管理员失败", e);
            return Result.error("初始化管理员失败：" + e.getMessage());
        }
    }
    
    /**
     * 批量删除用户（管理员功能）
     */
    @DeleteMapping("/batch")
    public Result<String> batchDeleteUsers(@RequestHeader("Authorization") String token,
                                         @RequestBody Map<String, List<Integer>> requestData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            List<Integer> userIds = requestData.get("userIds");
            if (userIds == null || userIds.isEmpty()) {
                return Result.error("用户ID列表不能为空");
            }
            
            userService.batchDeleteUsers(userIds);
            logger.info("批量删除用户: {}", userIds);
            return Result.success("批量删除成功");
        } catch (Exception e) {
            logger.error("批量删除用户失败", e);
            return Result.error("批量删除用户失败：" + e.getMessage());
        }
    }
    
    /**
     * 批量设置用户角色（管理员功能）
     */
    @PutMapping("/batch/role")
    public Result<String> batchSetRole(@RequestHeader("Authorization") String token,
                                     @RequestBody Map<String, Object> requestData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            @SuppressWarnings("unchecked")
            List<Integer> userIds = (List<Integer>) requestData.get("userIds");
            String role = (String) requestData.get("role");
            
            if (userIds == null || userIds.isEmpty()) {
                return Result.error("用户ID列表不能为空");
            }
            
            if (role == null) {
                return Result.error("角色不能为空");
            }
            
            userService.batchSetRole(userIds, role);
            logger.info("批量设置用户角色: {} -> {}", userIds, role);
            return Result.success("批量设置角色成功");
        } catch (Exception e) {
            logger.error("批量设置用户角色失败", e);
            return Result.error("批量设置用户角色失败：" + e.getMessage());
        }
    }

    /**
     * 批量设置用户状态（管理员功能）
     */
    @PutMapping("/batch/status")
    public Result<String> batchSetStatus(@RequestHeader("Authorization") String token,
                                       @RequestBody Map<String, Object> requestData) {
        try {
            Integer currentUserId = validateTokenAndGetUserId(token);
            
            @SuppressWarnings("unchecked")
            List<Integer> userIds = (List<Integer>) requestData.get("userIds");
            String status = (String) requestData.get("status");
            
            if (userIds == null || userIds.isEmpty()) {
                return Result.error("用户ID列表不能为空");
            }
            
            if (status == null) {
                return Result.error("状态不能为空");
            }
            
            userService.batchSetStatus(userIds, status);
            logger.info("批量设置用户状态: {} -> {}", userIds, status);
            return Result.success("批量设置状态成功");
        } catch (Exception e) {
            logger.error("批量设置用户状态失败", e);
            return Result.error("批量设置用户状态失败：" + e.getMessage());
        }
    }
} 